package com.whmskj.xjlhbc.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.extra.spring.SpringUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.whmskj.xjlhbc.core.Page;
import com.whmskj.xjlhbc.domain.*;
import com.whmskj.xjlhbc.dto.QueryDto;
import com.whmskj.xjlhbc.mapper.SublistOfDailyAttendanceRecordsFMapper;
import com.whmskj.xjlhbc.mapper.ThePlanesStrappedToATableMapper;
import com.whmskj.xjlhbc.service.IDailyAttendanceLogMasterTableService;
import com.whmskj.xjlhbc.service.IPersonnelManagementDataSheetsService;
import com.whmskj.xjlhbc.service.ISublistOfDailyAttendanceRecordsFService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class SublistOfDailyAttendanceRecordsFServiceImpl
        extends ServiceImpl<SublistOfDailyAttendanceRecordsFMapper, SublistOfDailyAttendanceRecordsF> implements ISublistOfDailyAttendanceRecordsFService {

    @Autowired
    private ThePlanesStrappedToATableMapper thePlanesStrappedToATableMapper;

    @Autowired
    private IDailyAttendanceLogMasterTableService dailyAttendanceLogMasterTableService;

    @Autowired
    private IPersonnelManagementDataSheetsService personnelManagementDataSheetsService;

    @Override
    public List<SublistOfDailyAttendanceRecordsF> queryList(QueryDto param) {
        List<String> className = param.isHasJth() ? getClassName() : personnelManagementDataSheetsService.getClassName();
        if(className.isEmpty()){
            return new ArrayList<>();
        }
        param.setDateOfAttendance(StringUtils.hasText(param.getDateOfAttendance()) ? param.getDateOfAttendance().substring(0,10) : LocalDate.now().toString());
        LambdaQueryWrapper<ThePlanesStrappedToATable> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ThePlanesStrappedToATable::getF7ba, param.getDateOfAttendance())
                .isNotNull(ThePlanesStrappedToATable::getNumberOfStations)
                .ne(ThePlanesStrappedToATable::getNumberOfStations,0);
        List<ThePlanesStrappedToATable> thePlanesStrappedToATables = thePlanesStrappedToATableMapper.selectList(wrapper);
        if(thePlanesStrappedToATables.isEmpty()) return new ArrayList<>();
        Page.startPage();
        List<String> nameOfEmployees = thePlanesStrappedToATables.stream().map(ThePlanesStrappedToATable::getNameOfPersonnel).distinct().collect(Collectors.toList());
        LambdaQueryChainWrapper<SublistOfDailyAttendanceRecordsF> queryWrapper = lambdaQuery().eq(SublistOfDailyAttendanceRecordsF::getDateOfAttendance, param.getDateOfAttendance())
                .eq(StringUtils.hasText(param.getAttendance4()), SublistOfDailyAttendanceRecordsF::getAttendance4, param.getAttendance4())
                .like(StringUtils.hasText(param.getNameOfEmployee()), SublistOfDailyAttendanceRecordsF::getNameOfEmployee, param.getNameOfEmployee())
                .like(StringUtils.hasText(param.getWorkNumber()), SublistOfDailyAttendanceRecordsF::getWorkNumber, param.getWorkNumber())
                .like(StringUtils.hasText(param.getPositionsToWhichTheyBelong()), SublistOfDailyAttendanceRecordsF::getPositionsToWhichTheyBelong, param.getPositionsToWhichTheyBelong())
                .like(StringUtils.hasText(param.getClassesToWhichTheyBelong()), SublistOfDailyAttendanceRecordsF::getClassesInTheClassroom, param.getClassesToWhichTheyBelong())
                .in(SublistOfDailyAttendanceRecordsF::getClassesInTheClassroom, className)
                .in(param.isHasJth(), SublistOfDailyAttendanceRecordsF::getNameOfEmployee, nameOfEmployees)
                .orderByDesc(SublistOfDailyAttendanceRecordsF::getId);
        List<SublistOfDailyAttendanceRecordsF> list = queryWrapper.list();
        if(list.isEmpty()) return new ArrayList<>();
        List<String> sublistOfDailyAttendanceRecordsFNameOfEmployees = list.stream().map(SublistOfDailyAttendanceRecordsF::getNameOfEmployee).distinct().collect(Collectors.toList());
        LambdaQueryWrapper<PersonnelManagementDataSheets> personnelManagementDataSheetsLambdaQueryWrapper = new LambdaQueryWrapper<>();
        personnelManagementDataSheetsLambdaQueryWrapper.in(PersonnelManagementDataSheets::getFe1e, sublistOfDailyAttendanceRecordsFNameOfEmployees);
        List<PersonnelManagementDataSheets> personnelManagementDataSheetsList = personnelManagementDataSheetsService.list(personnelManagementDataSheetsLambdaQueryWrapper);
        list.forEach(item->{
            String nameOfEmployee = item.getNameOfEmployee();
            ThePlanesStrappedToATable thePlanesStrappedToATable = thePlanesStrappedToATables.stream().filter(filter -> filter.getNameOfPersonnel().equals(nameOfEmployee)).findFirst().orElseGet(ThePlanesStrappedToATable::new);
            PersonnelManagementDataSheets personnelManagementDataSheets = personnelManagementDataSheetsList.stream().filter(filter -> filter.getFe1e().equals(nameOfEmployee)).findFirst().orElseGet(PersonnelManagementDataSheets::new);
            if(StringUtils.hasText(thePlanesStrappedToATable.getF657()))
                item.setJthList(Arrays.stream(thePlanesStrappedToATable.getF657().split(",")).collect(Collectors.toList()));
            item.setMobile(personnelManagementDataSheets.getFa8e());
            item.setDutyType1(personnelManagementDataSheets.getDutyType());
            item.setWorkingHours(personnelManagementDataSheets.getWorkingHours());
        });
        return list;
    }

    @Override
    public List<Object> queryPbzl(QueryDto param) {
        String date = StringUtils.hasText(param.getDateOfAttendance()) ? param.getDateOfAttendance().substring(0, 10) : LocalDate.now().toString();
        param.setDateOfAttendance(date);
        List<SublistOfDailyAttendanceRecordsF> selectList = lambdaQuery().eq(SublistOfDailyAttendanceRecordsF::getDateOfAttendance, param.getDateOfAttendance())
                .in(SublistOfDailyAttendanceRecordsF::getClassesInTheClassroom, "织布甲班", "织布乙班").list();
        List<String> classNames = selectList.stream().map(SublistOfDailyAttendanceRecordsF::getAttendance4).distinct().collect(Collectors.toList());
        Collections.reverse(classNames);
        LambdaQueryWrapper<ThePlanesStrappedToATable> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ThePlanesStrappedToATable::getF7ba, param.getDateOfAttendance())
                .isNotNull(ThePlanesStrappedToATable::getNumberOfStations)
                .ne(ThePlanesStrappedToATable::getNumberOfStations,0);
        //看台记录
        List<ThePlanesStrappedToATable> thePlanesStrappedToATables = thePlanesStrappedToATableMapper.selectList(wrapper);
        LambdaQueryChainWrapper<SublistOfDailyAttendanceRecordsF> queryWrapper = lambdaQuery().eq(SublistOfDailyAttendanceRecordsF::getDateOfAttendance, param.getDateOfAttendance())
                .in(StringUtils.hasText(param.getAttendance4()), SublistOfDailyAttendanceRecordsF::getAttendance4, classNames)
                .like(StringUtils.hasText(param.getNameOfEmployee()), SublistOfDailyAttendanceRecordsF::getNameOfEmployee, param.getNameOfEmployee())
                .like(StringUtils.hasText(param.getWorkNumber()), SublistOfDailyAttendanceRecordsF::getWorkNumber, param.getWorkNumber())
                .like(StringUtils.hasText(param.getPositionsToWhichTheyBelong()), SublistOfDailyAttendanceRecordsF::getPositionsToWhichTheyBelong, param.getPositionsToWhichTheyBelong())
                .like(StringUtils.hasText(param.getClassesToWhichTheyBelong()), SublistOfDailyAttendanceRecordsF::getClassesInTheClassroom, param.getClassesToWhichTheyBelong())
                .orderByDesc(SublistOfDailyAttendanceRecordsF::getId);
        List<SublistOfDailyAttendanceRecordsF> list = queryWrapper.list();
        if(list.isEmpty()) return new ArrayList<>();
        List<String> sublistOfDailyAttendanceRecordsFNameOfEmployees = list.stream().map(SublistOfDailyAttendanceRecordsF::getNameOfEmployee).distinct().collect(Collectors.toList());
        LambdaQueryWrapper<PersonnelManagementDataSheets> personnelManagementDataSheetsLambdaQueryWrapper = new LambdaQueryWrapper<>();
        personnelManagementDataSheetsLambdaQueryWrapper.in(PersonnelManagementDataSheets::getFe1e, sublistOfDailyAttendanceRecordsFNameOfEmployees);
        List<PersonnelManagementDataSheets> personnelManagementDataSheetsList = personnelManagementDataSheetsService.list(personnelManagementDataSheetsLambdaQueryWrapper);
        list.forEach(item->{
            String nameOfEmployee = item.getNameOfEmployee();
            ThePlanesStrappedToATable thePlanesStrappedToATable = thePlanesStrappedToATables.stream().filter(filter -> filter.getNameOfPersonnel().equals(nameOfEmployee)).findFirst().orElseGet(ThePlanesStrappedToATable::new);
            PersonnelManagementDataSheets personnelManagementDataSheets = personnelManagementDataSheetsList.stream().filter(filter -> filter.getFe1e().equals(nameOfEmployee)).findFirst().orElseGet(PersonnelManagementDataSheets::new);
            if(StringUtils.hasText(thePlanesStrappedToATable.getF657()))
                item.setJthList(Arrays.stream(thePlanesStrappedToATable.getF657().split(",")).collect(Collectors.toList()));
            item.setMobile(personnelManagementDataSheets.getFa8e());
            item.setDutyType1(personnelManagementDataSheets.getDutyType());
            item.setWorkingHours(personnelManagementDataSheets.getWorkingHours());
        });
        return classNames.stream().map(className -> {
            Map<String, Object> map = baseMapper.selectBcInfo(className);
            List<SublistOfDailyAttendanceRecordsF> dataList = list.stream().filter(f -> f.getAttendance4().equals(className)).collect(Collectors.toList());
            Map<String, Object> resultMap = new HashMap<>();
            resultMap.put("classInfo", map);
            resultMap.put("dataList", dataList);
            return resultMap;
        }).collect(Collectors.toList());
    }

    @Override
    public List<DailyAttendanceLogMasterTable> tjList(QueryDto param) {
        List<String> className = param.isHasJth() ? getClassName() : personnelManagementDataSheetsService.getClassName();
        if(className.isEmpty()){
            return new ArrayList<>();
        }
        Page.startPage();
        LambdaQueryWrapper<DailyAttendanceLogMasterTable> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(StringUtils.hasText(param.getDateOfAttendance()), DailyAttendanceLogMasterTable::getDateOfAttendance, param.getDateOfAttendance())
                .in(DailyAttendanceLogMasterTable::getClasses66, className)
                .orderByDesc(DailyAttendanceLogMasterTable::getDateOfAttendance);
        List<DailyAttendanceLogMasterTable> list = dailyAttendanceLogMasterTableService.list(queryWrapper);
        list.forEach(item-> {
            String classes66 = item.getClasses66();
            String classes = getClass(item.getDateOfAttendance(), item.getClasses66());
            item.setClasses66(classes66.concat("-").concat(classes));
            item.setClasses(classes);
        });
        return list;
    }

    //班次
    private String getClass(String dateOfAttendance, String className){
        SublistOfDailyAttendanceRecordsF sublistOfDailyAttendanceRecordsF = lambdaQuery().eq(SublistOfDailyAttendanceRecordsF::getDateOfAttendance, dateOfAttendance)
                .eq(SublistOfDailyAttendanceRecordsF::getClassesInTheClassroom, className).last("limit 1").one();
        if(Objects.isNull(sublistOfDailyAttendanceRecordsF)) return "";
        return StringUtils.hasText(sublistOfDailyAttendanceRecordsF.getAttendance4()) ? sublistOfDailyAttendanceRecordsF.getAttendance4() : "";
    }

    @Override
    @Transactional
    public boolean addDailyAttendance(SublistOfDailyAttendanceRecordsF body) throws Exception {
        CorpMember corpMember = getCorpMember();
//        body.setDateOfAttendance(LocalDate.now().toString());
        body.setSynchronisingFolderFailedSS(corpMember.getMemberId());
        body.setOtherOrganiser(corpMember.getMemberId());
        body.setAttendance(12L);
        body.setActualHoursWorked(BigDecimal.valueOf(1.0));
        body.setCreated(new Date());
        body.setUpdateTime(new Date());
        body.setAttendance2(CQ);
        PersonnelManagementDataSheets personnelManagementDataSheets = personnelManagementDataSheetsService.getByLoginUserId();
        body.setDutyType(personnelManagementDataSheets.getDutyType());
        String class22 = personnelManagementDataSheets.getClass22();
        SublistOfDailyAttendanceRecordsF sublistOfDailyAttendanceRecordsF = lambdaQuery().eq(SublistOfDailyAttendanceRecordsF::getNameOfEmployee, body.getNameOfEmployee())
                .eq(SublistOfDailyAttendanceRecordsF::getDateOfAttendance, body.getDateOfAttendance()).last("limit 1").one();
        if(Objects.nonNull(sublistOfDailyAttendanceRecordsF)){
            if(sublistOfDailyAttendanceRecordsF.getClassesInTheClassroom().equals(class22)){
                throw new Exception("该员工"+body.getNameOfEmployee()+"已在您今日的考勤组中！");
            }else {
                removeDailyAttendance(sublistOfDailyAttendanceRecordsF.getId().toString());
            }
        }
        LambdaQueryWrapper<PersonnelManagementDataSheets> personnelManagementDataSheetsLambdaQueryWrapper = new LambdaQueryWrapper<>();
        personnelManagementDataSheetsLambdaQueryWrapper.eq(PersonnelManagementDataSheets::getFe1e, body.getNameOfEmployee());
        PersonnelManagementDataSheets personnelManagementDataSheetsServiceOne = personnelManagementDataSheetsService.getOne(personnelManagementDataSheetsLambdaQueryWrapper);
        body.setClassesInTheClassroom(class22);
        body.setIdNumber(personnelManagementDataSheetsServiceOne.getIdNumber());
        body.setPositionsToWhichTheyBelong(personnelManagementDataSheetsServiceOne.getPositions1());
        body.setClassesToWhichTheyBelong(personnelManagementDataSheetsServiceOne.getClass22());
        updateDailyAttendanceLogMasterTable(body,1);
        return save(body);
    }

    private static final String CQ = "出勤";
    private static final String ZBG = "织布工";

    @Override
    @Transactional
    public boolean updateDailyAttendance(SublistOfDailyAttendanceRecordsF body) {
        CorpMember corpMember = getCorpMember();
//        body.setDateOfAttendance(LocalDate.now().toString());
        body.setSynchronisingFolderFailedSS(corpMember.getMemberId());
        body.setOtherOrganiser(corpMember.getMemberId());
        body.setUpdateTime(new Date());
        String bodyAttendance2 = body.getAttendance2();
        if (bodyAttendance2.equals(CQ)) {
            body.setReasonsForAbsenceFromWork("");
        }
        body.setIdNumber(null);
        SublistOfDailyAttendanceRecordsF sublistOfDailyAttendanceRecordsF = getById(body.getId());
        String attendance21 = sublistOfDailyAttendanceRecordsF.getAttendance2();
        if(!bodyAttendance2.equals(attendance21)) {
            updateDailyAttendanceLogMasterTable(sublistOfDailyAttendanceRecordsF, -1);
            body.setClassesInTheClassroom(sublistOfDailyAttendanceRecordsF.getClassesInTheClassroom());
            updateDailyAttendanceLogMasterTable(body, 1);
        }
        String dutyStations = body.getDutyStations();
        LambdaQueryWrapper<ThePlanesStrappedToATable> wrapper1 = new LambdaQueryWrapper<>();
        wrapper1.eq(ThePlanesStrappedToATable::getNameOfPersonnel, body.getNameOfEmployee())
                .eq(ThePlanesStrappedToATable::getF7ba, body.getDateOfAttendance()).last("limit 1");
        if(!dutyStations.equals(ZBG)){
            thePlanesStrappedToATableMapper.delete(wrapper1);
        }else {
            ThePlanesStrappedToATable thePlanesStrappedToATable = Optional.ofNullable(thePlanesStrappedToATableMapper.selectOne(wrapper1)).orElseGet(ThePlanesStrappedToATable::new);
            thePlanesStrappedToATable.setF7ba(body.getDateOfAttendance());
            thePlanesStrappedToATable.setNameOfPersonnel(body.getNameOfEmployee());
            thePlanesStrappedToATable.setWorkNumber(body.getWorkNumber());
            thePlanesStrappedToATable.setOperator(body.getSynchronisingFolderFailedSS());
            thePlanesStrappedToATable.setOperationTime(new Date());
            thePlanesStrappedToATable.setNameworkNumber(body.getNameOfEmployee().concat("/").concat(body.getWorkNumber() + ""));
            thePlanesStrappedToATable.setClass1(sublistOfDailyAttendanceRecordsF.getClassesInTheClassroom());
            thePlanesStrappedToATable.setClasses5(body.getAttendance4());
            thePlanesStrappedToATable.setF657(StringUtils.collectionToCommaDelimitedString(body.getJthList()));
            thePlanesStrappedToATable.setNumberOfStations((long) body.getJthList().size());
            int result = Objects.isNull(thePlanesStrappedToATable.getId()) ? thePlanesStrappedToATableMapper.insert(thePlanesStrappedToATable) : thePlanesStrappedToATableMapper.updateById(thePlanesStrappedToATable);
        }
        return updateById(body);
    }

    @Override
    @Transactional
    public boolean removeDailyAttendance(String id) {
        SublistOfDailyAttendanceRecordsF sublistOfDailyAttendanceRecordsF = getById(id);
        updateDailyAttendanceLogMasterTable(sublistOfDailyAttendanceRecordsF,-1);
        return removeById(id);
    }

    @Override
    public List<String> getClassName() {
        int hour = DateUtil.date().hour(true);
        String today = DateUtil.today();
        String atten = hour > 9 && hour <= 21 ? "早" : "晚";
        if(hour<=9){
            today = DateUtil.yesterday().toDateStr();
        }
        SublistOfDailyAttendanceRecordsF one = Optional.ofNullable(lambdaQuery().eq(SublistOfDailyAttendanceRecordsF::getDateOfAttendance, today)
                .like(SublistOfDailyAttendanceRecordsF::getAttendance4,atten)
                .last("limit 1").one()).orElseGet(SublistOfDailyAttendanceRecordsF::new);
        String classesInTheClassroom = one.getClassesInTheClassroom();
        classesInTheClassroom = StringUtils.hasText(classesInTheClassroom) ? classesInTheClassroom : "织布甲班";
        return Collections.singletonList(classesInTheClassroom);
    }

    private void updateDailyAttendanceLogMasterTable(SublistOfDailyAttendanceRecordsF sublistOfDailyAttendanceRecordsF,int num){
        LambdaQueryWrapper<DailyAttendanceLogMasterTable> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DailyAttendanceLogMasterTable::getDateOfAttendance, sublistOfDailyAttendanceRecordsF.getDateOfAttendance())
                .eq(DailyAttendanceLogMasterTable::getClasses66, sublistOfDailyAttendanceRecordsF.getClassesInTheClassroom()).last("limit 1");
        DailyAttendanceLogMasterTable dailyAttendanceLogMasterTable = dailyAttendanceLogMasterTableService.getOne(wrapper);
        if(Objects.nonNull(dailyAttendanceLogMasterTable)) {
            DailyAttendanceLogMasterTable attendanceLogMasterTable = new DailyAttendanceLogMasterTable();
            attendanceLogMasterTable.setId(dailyAttendanceLogMasterTable.getId());
            if(sublistOfDailyAttendanceRecordsF.getAttendance2().equals(CQ)) {
                attendanceLogMasterTable.setNumberOfPersonsInAttendance(dailyAttendanceLogMasterTable.getNumberOfPersonsInAttendance() + num);
                attendanceLogMasterTable.setNumberOfStaffManaged(Math.max(dailyAttendanceLogMasterTable.getNumberOfStaffManaged(), attendanceLogMasterTable.getNumberOfPersonsInAttendance()));
            }
            if(sublistOfDailyAttendanceRecordsF.getAttendance2().equals("缺勤")){
                attendanceLogMasterTable.setNumberOfAbsentees(dailyAttendanceLogMasterTable.getNumberOfAbsentees() + num);
            }
            if(sublistOfDailyAttendanceRecordsF.getAttendance2().equals("休息")){
                attendanceLogMasterTable.setNumberOfPersonsResting(dailyAttendanceLogMasterTable.getNumberOfPersonsResting() + num);
            }
            if(sublistOfDailyAttendanceRecordsF.getAttendance2().equals("离职")){
                attendanceLogMasterTable.setSeparations(dailyAttendanceLogMasterTable.getSeparations() + num);
            }
            dailyAttendanceLogMasterTableService.updateById(attendanceLogMasterTable);
        }
    }

    private CorpMember getCorpMember(){
        IPersonnelManagementDataSheetsService personnel = SpringUtil.getBean(IPersonnelManagementDataSheetsService.class);
        return personnel.getCorpMemberByLogin();
    }
}
